package com.briup.day11;

import java.util.Arrays;

public interface Action {
    /**
     * 将传入的字符串，按照一定的规则进行分割，
     * 然后返回分割后的字符串数组
     *
     * @param str 需要分割的字符串
     * @return 分割后得到的字符串数组
     */
    String[] test(String str);
}

interface Action2 {
    // 打印你输出的内容
    void print(Object o);
}

class Test2 {
    public static void main(String[] args) {
        // 要分割 "a-b-c"
        Action a = new Action() {
            @Override
            public String[] test(String str) {
                // String类中的split方法能够将调用该方法的字符串对象，
                // 按照你传入的规则进行分割，该规则使用正则表达式进行描述
                return str.split("[-]");
            }
        };
        String[] test = a.test("a-b-c");
        System.out.println(Arrays.toString(test));

        System.out.println("==========================");

        // 要分割 a|b|c
        // 在匿名内部类中，实现接口，本质上就是为了实现接口的抽象方法
        // 既然本质上是为了实现该抽象方法，那么是否可以直接只编写方法的实现逻辑，
        // 不用管接口实现类的其他结构内容  ===> lambda表达式
        /*
         lambda表达式：() -> {}
            其中()表示要实现抽象方法的参数列表，有几个参数就写几个参数的名字，
            注意不需要编写参数的类型，因为lambda表达式在执行时会自动推测参数的类型
            -> 是lambda表达式固定的内容，相当于是()和{}的连接，表示由参数传入后执行
            {}内的方法实现逻辑
         lambda表达式，只能用于简化函数式接口，
         函数式接口指的是只有一个抽象方法的接口，函数式接口除了只能定义一个抽象方法外，
         其他和普通的接口一致，都可以定义静态方法、私有方法等内容
         */
        Action b = (str) -> {
            return str.split("[|]");
        };
        String[] test2 = b.test("a|b|C");

        // 实现Action2，打印输出test2数组内容
        /*
        lambda表达式的本质就是为了实现接口中唯一的抽象方法，
         如果存在一个同质的以及实现好的方法，
         我们是否可以借助该方法完成我们对抽象方法的实现？
         可以，我们可以使用方法引用，借助已经实现好的方法，完成对抽象方法的实现

         方法引用的结构：
            用于调用右边方法的对象::接替抽象方法实现的方法的名字
            obj::methodName
         */
        // 我们要实现的Action2接口中的print方法，是一个单参无返回值的方法，
        // 并且该方法的作用是打印输出内容到控制台中；
        // 那么该方法与System类中的out对象的println方法同质，那么我们就可以借助于
        // System.out中的println方法来实现抽象方法；
        Action2 action2 = System.out::println;
        action2.print(Arrays.toString(test2));
    }

    private void test() {
        // 如果接替实现抽象方法的具体方法与匿名内部类所在的方法位于同一个类中，
        // 并且这两个方法都是成员方法时，可以使用this关键字作为调用右侧方法的对象
        Action2 a = this::print;
    }

    private void print(Object o) {
        System.out.println(o);
    }
}
